#ifndef _IINPUT_HPP
#define _IINPUT_HPP

#include <cstddef> // For size_t
#include "Maths.hpp" // For Vector

typedef size_t Key;
typedef size_t Button;

class IInput
{
public:
	virtual ~IInput() {}
	
	//virtual bool getKeyState(Key key) const = 0;
	//virtual Vector getMousePos() const      = 0;
	
	// Gather input
	virtual void update()                     = 0;
};

class IInputHandler
{
public:
	virtual ~IInputHandler() {}
	
	virtual void onKeyDown(IInput* caller, Key key)                     = 0;
	virtual void onKeyUp(IInput* caller, Key key)                       = 0;
	
	virtual void onMouseDown(IInput* caller, Vector pos, Button button) = 0;
	virtual void onMouseUp(IInput* caller, Vector pos, Button button)   = 0;
	virtual void onMouseMove(IInput* caller, Vector pos, Button button) = 0;

	virtual void onQuit(IInput* caller)                                 = 0;
};

// Note: These keycodes are copied from SDL
enum KeyCode {
        /** @name ASCII mapped keysyms
         *  The keyboard syms have been cleverly chosen to map to ASCII
         */
        /*@{*/
	GK_UNKNOWN		= 0,
	GK_FIRST		= 0,
	GK_BACKSPACE		= 8,
	GK_TAB		= 9,
	GK_CLEAR		= 12,
	GK_RETURN		= 13,
	GK_PAUSE		= 19,
	GK_ESCAPE		= 27,
	GK_SPACE		= 32,
	GK_EXCLAIM		= 33,
	GK_QUOTEDBL		= 34,
	GK_HASH		= 35,
	GK_DOLLAR		= 36,
	GK_AMPERSAND		= 38,
	GK_QUOTE		= 39,
	GK_LEFTPAREN		= 40,
	GK_RIGHTPAREN		= 41,
	GK_ASTERISK		= 42,
	GK_PLUS		= 43,
	GK_COMMA		= 44,
	GK_MINUS		= 45,
	GK_PERIOD		= 46,
	GK_SLASH		= 47,
	GK_0			= 48,
	GK_1			= 49,
	GK_2			= 50,
	GK_3			= 51,
	GK_4			= 52,
	GK_5			= 53,
	GK_6			= 54,
	GK_7			= 55,
	GK_8			= 56,
	GK_9			= 57,
	GK_COLON		= 58,
	GK_SEMICOLON		= 59,
	GK_LESS		= 60,
	GK_EQUALS		= 61,
	GK_GREATER		= 62,
	GK_QUESTION		= 63,
	GK_AT			= 64,
	/* 
	   Skip uppercase letters
	 */
	GK_LEFTBRACKET	= 91,
	GK_BACKSLASH		= 92,
	GK_RIGHTBRACKET	= 93,
	GK_CARET		= 94,
	GK_UNDERSCORE		= 95,
	GK_BACKQUOTE		= 96,
	GK_a			= 97,
	GK_b			= 98,
	GK_c			= 99,
	GK_d			= 100,
	GK_e			= 101,
	GK_f			= 102,
	GK_g			= 103,
	GK_h			= 104,
	GK_i			= 105,
	GK_j			= 106,
	GK_k			= 107,
	GK_l			= 108,
	GK_m			= 109,
	GK_n			= 110,
	GK_o			= 111,
	GK_p			= 112,
	GK_q			= 113,
	GK_r			= 114,
	GK_s			= 115,
	GK_t			= 116,
	GK_u			= 117,
	GK_v			= 118,
	GK_w			= 119,
	GK_x			= 120,
	GK_y			= 121,
	GK_z			= 122,
	GK_DELETE		= 127,
	/* End of ASCII mapped keysyms */
        /*@}*/

	/** @name International keyboard syms */
        /*@{*/
	GK_WORLD_0		= 160,		/* 0xA0 */
	GK_WORLD_1		= 161,
	GK_WORLD_2		= 162,
	GK_WORLD_3		= 163,
	GK_WORLD_4		= 164,
	GK_WORLD_5		= 165,
	GK_WORLD_6		= 166,
	GK_WORLD_7		= 167,
	GK_WORLD_8		= 168,
	GK_WORLD_9		= 169,
	GK_WORLD_10		= 170,
	GK_WORLD_11		= 171,
	GK_WORLD_12		= 172,
	GK_WORLD_13		= 173,
	GK_WORLD_14		= 174,
	GK_WORLD_15		= 175,
	GK_WORLD_16		= 176,
	GK_WORLD_17		= 177,
	GK_WORLD_18		= 178,
	GK_WORLD_19		= 179,
	GK_WORLD_20		= 180,
	GK_WORLD_21		= 181,
	GK_WORLD_22		= 182,
	GK_WORLD_23		= 183,
	GK_WORLD_24		= 184,
	GK_WORLD_25		= 185,
	GK_WORLD_26		= 186,
	GK_WORLD_27		= 187,
	GK_WORLD_28		= 188,
	GK_WORLD_29		= 189,
	GK_WORLD_30		= 190,
	GK_WORLD_31		= 191,
	GK_WORLD_32		= 192,
	GK_WORLD_33		= 193,
	GK_WORLD_34		= 194,
	GK_WORLD_35		= 195,
	GK_WORLD_36		= 196,
	GK_WORLD_37		= 197,
	GK_WORLD_38		= 198,
	GK_WORLD_39		= 199,
	GK_WORLD_40		= 200,
	GK_WORLD_41		= 201,
	GK_WORLD_42		= 202,
	GK_WORLD_43		= 203,
	GK_WORLD_44		= 204,
	GK_WORLD_45		= 205,
	GK_WORLD_46		= 206,
	GK_WORLD_47		= 207,
	GK_WORLD_48		= 208,
	GK_WORLD_49		= 209,
	GK_WORLD_50		= 210,
	GK_WORLD_51		= 211,
	GK_WORLD_52		= 212,
	GK_WORLD_53		= 213,
	GK_WORLD_54		= 214,
	GK_WORLD_55		= 215,
	GK_WORLD_56		= 216,
	GK_WORLD_57		= 217,
	GK_WORLD_58		= 218,
	GK_WORLD_59		= 219,
	GK_WORLD_60		= 220,
	GK_WORLD_61		= 221,
	GK_WORLD_62		= 222,
	GK_WORLD_63		= 223,
	GK_WORLD_64		= 224,
	GK_WORLD_65		= 225,
	GK_WORLD_66		= 226,
	GK_WORLD_67		= 227,
	GK_WORLD_68		= 228,
	GK_WORLD_69		= 229,
	GK_WORLD_70		= 230,
	GK_WORLD_71		= 231,
	GK_WORLD_72		= 232,
	GK_WORLD_73		= 233,
	GK_WORLD_74		= 234,
	GK_WORLD_75		= 235,
	GK_WORLD_76		= 236,
	GK_WORLD_77		= 237,
	GK_WORLD_78		= 238,
	GK_WORLD_79		= 239,
	GK_WORLD_80		= 240,
	GK_WORLD_81		= 241,
	GK_WORLD_82		= 242,
	GK_WORLD_83		= 243,
	GK_WORLD_84		= 244,
	GK_WORLD_85		= 245,
	GK_WORLD_86		= 246,
	GK_WORLD_87		= 247,
	GK_WORLD_88		= 248,
	GK_WORLD_89		= 249,
	GK_WORLD_90		= 250,
	GK_WORLD_91		= 251,
	GK_WORLD_92		= 252,
	GK_WORLD_93		= 253,
	GK_WORLD_94		= 254,
	GK_WORLD_95		= 255,		/* 0xFF */
        /*@}*/

	/** @name Numeric keypad */
        /*@{*/
	GK_KP0		= 256,
	GK_KP1		= 257,
	GK_KP2		= 258,
	GK_KP3		= 259,
	GK_KP4		= 260,
	GK_KP5		= 261,
	GK_KP6		= 262,
	GK_KP7		= 263,
	GK_KP8		= 264,
	GK_KP9		= 265,
	GK_KP_PERIOD		= 266,
	GK_KP_DIVIDE		= 267,
	GK_KP_MULTIPLY	= 268,
	GK_KP_MINUS		= 269,
	GK_KP_PLUS		= 270,
	GK_KP_ENTER		= 271,
	GK_KP_EQUALS		= 272,
        /*@}*/

	/** @name Arrows + Home/End pad */
        /*@{*/
	GK_UP			= 273,
	GK_DOWN		= 274,
	GK_RIGHT		= 275,
	GK_LEFT		= 276,
	GK_INSERT		= 277,
	GK_HOME		= 278,
	GK_END		= 279,
	GK_PAGEUP		= 280,
	GK_PAGEDOWN		= 281,
        /*@}*/

	/** @name Function keys */
        /*@{*/
	GK_F1			= 282,
	GK_F2			= 283,
	GK_F3			= 284,
	GK_F4			= 285,
	GK_F5			= 286,
	GK_F6			= 287,
	GK_F7			= 288,
	GK_F8			= 289,
	GK_F9			= 290,
	GK_F10		= 291,
	GK_F11		= 292,
	GK_F12		= 293,
	GK_F13		= 294,
	GK_F14		= 295,
	GK_F15		= 296,
        /*@}*/

	/** @name Key state modifier keys */
        /*@{*/
	GK_NUMLOCK		= 300,
	GK_CAPSLOCK		= 301,
	GK_SCROLLOCK		= 302,
	GK_RSHIFT		= 303,
	GK_LSHIFT		= 304,
	GK_RCTRL		= 305,
	GK_LCTRL		= 306,
	GK_RALT		= 307,
	GK_LALT		= 308,
	GK_RMETA		= 309,
	GK_LMETA		= 310,
	GK_LSUPER		= 311,		/**< Left "Windows" key */
	GK_RSUPER		= 312,		/**< Right "Windows" key */
	GK_MODE		= 313,		/**< "Alt Gr" key */
	GK_COMPOSE		= 314,		/**< Multi-key compose key */
        /*@}*/

	/** @name Miscellaneous function keys */
        /*@{*/
	GK_HELP		= 315,
	GK_PRINT		= 316,
	GK_SYSREQ		= 317,
	GK_BREAK		= 318,
	GK_MENU		= 319,
	GK_POWER		= 320,		/**< Power Macintosh power key */
	GK_EURO		= 321,		/**< Some european keyboards */
	GK_UNDO		= 322,		/**< Atari keyboard has Undo */
        /*@}*/

	/* Add any other keys here */

	GK_LAST
};

/** Enumeration of valid key mods (possibly OR'd together) */
enum KeyMod {
	GKMOD_NONE  = 0x0000,
	GKMOD_LSHIFT= 0x0001,
	GKMOD_RSHIFT= 0x0002,
	GKMOD_LCTRL = 0x0040,
	GKMOD_RCTRL = 0x0080,
	GKMOD_LALT  = 0x0100,
	GKMOD_RALT  = 0x0200,
	GKMOD_LMETA = 0x0400,
	GKMOD_RMETA = 0x0800,
	GKMOD_NUM   = 0x1000,
	GKMOD_CAPS  = 0x2000,
	GKMOD_MODE  = 0x4000,
	GKMOD_RESERVED = 0x8000,
	
	GKMOD_CTRL  = GKMOD_LCTRL | GKMOD_RCTRL,
	GKMOD_SHIFT = GKMOD_LSHIFT | GKMOD_RSHIFT,
	GKMOD_ALT   = GKMOD_LALT | GKMOD_RALT,
    GKMOD_META  = GKMOD_LMETA | GKMOD_RMETA
};

#endif //_IINPUT_HPP
